#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

#include <sys/ipc.h>

#include "envdata.h"
#include "squeue.h"
#include "sem.h"
#include "shm.h"
#include "handler_proc.h"
#include "handler_recv.h"
#include "handler_cmd.h"
#include "handler_serial.h"
#include "handler_settemp.h"

//信号量相关
extern key_t key;
extern int semid;
extern int pid;
extern union semun mysemun;
extern struct sembuf P,V;

//共享内存相关
extern int shmid;
extern void *shmaddr;

//队列相关
extern squeue *sq;

//ttyUSB串口
extern int dev_uart_fd;

//是否填充了数据的标志
int haveData = 0; 

typedef struct sockaddr SA;

/**
 *@breif:主程序
 *@param:argc argv
 *@return 0：success 1：error
 *@author：马德顺
 */
int main(int argc, const char *argv[])
{
	
		//变量初始化
		pthread_t tid_recv;
		pthread_t tid_proc;
		pthread_t tid_cmd;
		pthread_t tid_settemp;
		int serverfd,clientfd;
		char buf[32]={0};
		struct sockaddr_in serveraddr,clientaddr;
		socklen_t len=sizeof(serveraddr);
		bzero(&serveraddr,len);

		//输入格式验证./server ip port
		if(argc<3)
		{
			fprintf(stderr,"USER:%s IP PORT",argv[0]);
			return -1;
		}

		//初始化信号量
		init_sem();
		
		//初始化共享内存
		init_shm();

		//创建队列
		sq = queue_create();

		//创建流式套接字
		if((serverfd=socket(AF_INET,SOCK_STREAM,0))<0)
		{
			perror("fail to socketi:");
			return -1;
		}

		//填充本地的网络信息
		serveraddr.sin_family = AF_INET;
		serveraddr.sin_port = htons(atoi(argv[2]));
		serveraddr.sin_addr.s_addr = inet_addr(argv[1]);

		//绑定网络信息
		if(bind(serverfd,(SA*)&serveraddr,len)<0)
		{
			perror("fail to bind:");
			return -1;
		}	

		//监听套接字
		if(listen(serverfd,10)<0)
		{
			perror("fail to listen:");
			return -1;
		}

		//创建处理线程
		if(pthread_create(&tid_proc,NULL,handler_proc,NULL) == -1)
		{
			perror("handler_proc_create");
			return -1;
		}

		//创建接收下行命令的线程
		if(pthread_create(&tid_cmd,NULL,handler_cmd,NULL) == -1)
		{
			perror("handler_cmd_create");
			return -1;
		}

		//创建设置温度报警的线程
		if(pthread_create(&tid_settemp,NULL,handler_settemp,NULL) == -1)
		{
			perror("handler_cmd_create");
			return -1;
		}


		while(1)
		{
			//等待客户端连接
			if((clientfd=accept(serverfd,(SA*)&clientaddr,&len))<0)
			{
				perror("fail to accept:");
				return -1;
			}
			
			//打印客户端的网络信息
			printf("%s-------%u\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));
			
			//创建接收线程
			if(pthread_create(&tid_recv,NULL,handler_recv,&clientfd) == -1)
			{
				perror("pthread_recv_create");
				return -1;
			}

			//等待接收线程退出
			pthread_join(tid_recv,(void *)&buf); 
			
			//关闭套接字
			close(clientfd);
		}
		
		//等待线程退出
		pthread_join(tid_proc,(void *)&buf); 
		pthread_join(tid_cmd,(void *)&buf); 
		pthread_join(tid_settemp,(void *)&buf); 

		close(serverfd);
		delete_shm();

		return 0;
}